/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
'use strict';

/* eslint-disable */
export namespace vscMockPosition {
    /**
     * A position in the editor. This interface is suitable for serialization.
     */
    export interface IPosition {
        /**
         * line number (starts at 1)
         */
        readonly lineNumber: number;
        /**
         * column (the first character in a line is between column 1 and column 2)
         */
        readonly column: number;
    }

    /**
     * A position in the editor.
     */
    export class Position {
        /**
         * line number (starts at 1)
         */
        public readonly lineNumber: number;
        /**
         * column (the first character in a line is between column 1 and column 2)
         */
        public readonly column: number;

        constructor(lineNumber: number, column: number) {
            this.lineNumber = lineNumber;
            this.column = column;
        }

        /**
         * Test if this position equals other position
         */
        public equals(other: IPosition): boolean {
            return Position.equals(this, other);
        }

        /**
         * Test if position `a` equals position `b`
         */
        public static equals(a: IPosition, b: IPosition): boolean {
            if (!a && !b) {
                return true;
            }
            return !!a && !!b && a.lineNumber === b.lineNumber && a.column === b.column;
        }

        /**
         * Test if this position is before other position.
         * If the two positions are equal, the result will be false.
         */
        public isBefore(other: IPosition): boolean {
            return Position.isBefore(this, other);
        }

        /**
         * Test if position `a` is before position `b`.
         * If the two positions are equal, the result will be false.
         */
        public static isBefore(a: IPosition, b: IPosition): boolean {
            if (a.lineNumber < b.lineNumber) {
                return true;
            }
            if (b.lineNumber < a.lineNumber) {
                return false;
            }
            return a.column < b.column;
        }

        /**
         * Test if this position is before other position.
         * If the two positions are equal, the result will be true.
         */
        public isBeforeOrEqual(other: IPosition): boolean {
            return Position.isBeforeOrEqual(this, other);
        }

        /**
         * Test if position `a` is before position `b`.
         * If the two positions are equal, the result will be true.
         */
        public static isBeforeOrEqual(a: IPosition, b: IPosition): boolean {
            if (a.lineNumber < b.lineNumber) {
                return true;
            }
            if (b.lineNumber < a.lineNumber) {
                return false;
            }
            return a.column <= b.column;
        }

        /**
         * A function that compares positions, useful for sorting
         */
        public static compare(a: IPosition, b: IPosition): number {
            let aLineNumber = a.lineNumber | 0;
            let bLineNumber = b.lineNumber | 0;

            if (aLineNumber === bLineNumber) {
                let aColumn = a.column | 0;
                let bColumn = b.column | 0;
                return aColumn - bColumn;
            }

            return aLineNumber - bLineNumber;
        }

        /**
         * Clone this position.
         */
        public clone(): Position {
            return new Position(this.lineNumber, this.column);
        }

        /**
         * Convert to a human-readable representation.
         */
        public toString(): string {
            return '(' + this.lineNumber + ',' + this.column + ')';
        }

        // ---

        /**
         * Create a `Position` from an `IPosition`.
         */
        public static lift(pos: IPosition): Position {
            return new Position(pos.lineNumber, pos.column);
        }

        /**
         * Test if `obj` is an `IPosition`.
         */
        public static isIPosition(obj: any): obj is IPosition {
            return obj && typeof obj.lineNumber === 'number' && typeof obj.column === 'number';
        }
    }
}
